<template>
  <div>
    <search-line>
      <div slot="rightButtons">
        <el-button v-permission="'user_character_create'" type="primary" icon="el-icon-plus" @click="showAddRoles">
          新建
        </el-button>
      </div>
    </search-line>
    <x-table v-loading="tableLoading" v-bind="tableOption" @changePage="changeTablePage" @clickBtn="clickTableBtn" />
    <x-dialog :visible.sync="addDialogVisible" :title="isEdit ? '编辑' : '新增'" @submit="addRole" @close="closeAddDialog">
      <el-form ref="addForm" :model="addForm" label-width="100px">
        <el-form-item prop="name" label="名称" :rules="rules.name">
          <el-input v-model="addForm.name" placeholder="请输入角色名称" />
        </el-form-item>
        <el-form-item prop="code" label="编码" :rules="[rules.required, rules.code]">
          <el-input v-model="addForm.code" placeholder="请输入角色编码" />
        </el-form-item>
        <el-form-item prop="description" label="描述" :rules="[rules.required, rules.description]">
          <el-input v-model="addForm.description" type="textarea" :rows="4" placeholder="请输入角色描述" />
        </el-form-item>
      </el-form>
    </x-dialog>
    <x-dialog
      :visible.sync="memberDialogVisible"
      :title="'成员管理 / ' + currentRow.name"
      width="680px"
      :has-footer="false"
      @close="closeMemberDialog"
    >
      <radio-transfer
        v-loading="memberDialogLoading"
        :total-list="totalList"
        :value-list="currentUserList"
        height="400px"
        :default-props="transferProps"
        :right-loading="rightLoading"
        @transfer="moveMember"
      />
    </x-dialog>
    <el-drawer
      class="detail-drawer"
      :visible.sync="authorityDialogVisible"
      direction="rtl"
      :wrapper-closable="false"
      :title="'权限配置 / ' + currentRow.name"
      @close="authorityDialogClose"
    >
      <div v-loading="authorityDialogLoading" class="flex-column body">
        <el-tree
          ref="menuTree"
          class="flex-1"
          :data="menus"
          default-expand-all
          show-checkbox
          :props="defaultProps"
          check-on-click-node
          node-key="permissionId"
          :default-checked-keys="defaultTreeChecked"
          :expand-on-click-node="false"
        />
        <div class="footer text-center">
          <el-button size="mini" @click="authorityDialogVisible = false">
            取消
          </el-button>
          <el-button type="primary" size="mini" @click="submitAuth">
            确定
          </el-button>
        </div>
      </div>
    </el-drawer>
  </div>
</template>
<script>
import searchLine from '../../components/searchLine'
import radioTransfer from '../../components/radioTransfer'
import * as api from '../../api/user'
import { cloneDeep } from 'lodash'
import rules from '../../utils/rules.js'
import { roleList } from './data'
import { hint } from '../../utils/tools'

export default {
  components: { searchLine, radioTransfer },
  data() {
    return {
      authorityDialogVisible: false,
      authorityDialogLoading: false,
      menus: [
        {
          id: '0',
          name: '管理后台',
          child: []
        }
      ],
      defaultProps: {
        children: 'child',
        label: 'name',
        type: 0
      },
      transferProps: {
        label: 'username',
        value: 'memberId'
      },
      memberDialogVisible: false,
      memberDialogLoading: false,
      tableLoading: false,
      searchObj: {},
      tableOption: roleList,
      params: {
        pageIndex: 1,
        pageSize: 10
      },
      defaultTreeChecked: [],
      permissionIds: [],
      addDialogVisible: false,
      isEdit: false,
      addForm: {},
      userList: [],
      totalList: [],
      currentRow: {},
      currentUserList: [],
      rightLoading: false,
      rules
    }
  },
  created() {
    this.getList()
  },
  mounted() {
    this.getMenus()
  },
  methods: {
    authorityDialogClose() {
      this.$refs.menuTree.setCheckedKeys([])
      this.defaultTreeChecked = []
    },
    submitAuth() {
      const checkNodes = this.$refs.menuTree.getCheckedNodes(false, true)
      const checkKeys = checkNodes.map((item) => item.permissionId)
      checkKeys.shift()
      api
        .editRole({
          code: this.currentRow.code,
          description: this.currentRow.description,
          name: this.currentRow.name,
          permissionIds: checkKeys,
          roleId: this.currentRow.id
        })
        .then((res) => {
          hint.success('操作成功')
          this.authorityDialogVisible = false
        })
    },
    getMenus() {
      api.getMenus().then((res) => {
        const menus = res.filter(item => item.hidden !== 1)
        this.$set(this.menus[0], 'child', menus)
      })
    },
    moveMember({ direction, item }) {
      if (direction === 'left') {
        api.roleUnbindUser({
          memberIds: [item.memberId],
          roleId: this.currentRow.id
        })
      } else {
        api.roleBindUser({
          memberIds: [item.memberId],
          roleId: this.currentRow.id
        })
      }
    },
    getUserList() {
      this.memberDialogLoading = true
      api.getUnbindUserList().then((res) => {
        this.memberDialogLoading = false
        this.$set(this, 'userList', res)
        this.getUserListByRole()
      })
    },
    getList() {
      this.tableLoading = true
      api
        .getRoleList(this.params)
        .then((res) => {
          this.tableOption.data = res.records
          this.tableOption.pages.total = +res.data.total
          this.tableOption.pages.page = +this.params.pageIndex
          this.tableLoading = false

          if (res.data.records.length === 0 && this.params.pageIndex > 1) {
            this.params.pageIndex--
            this.getList()
          }
        })
        .catch((e) => {
          this.tableLoading = false
        })
    },
    closeMemberDialog() {},
    showAddRoles() {
      this.isEdit = false
      this.addDialogVisible = true
    },
    addRole() {
      this.$refs.addForm.validate((valid) => {
        if (valid) {
          if (this.isEdit) {
            this.addForm.roleId = this.currentRow.id
            this.addForm.permissionIds = this.permissionIds
            api.editRole(this.addForm).then((res) => {
              hint.success('操作成功')
              this.addDialogVisible = false
              this.getList()
            })
          } else {
            api.addRole(this.addForm).then((res) => {
              this.addDialogVisible = false
              hint.success('操作成功')
              this.getList()
            })
          }
        }
      })
    },
    closeAddDialog() {
      this.addForm = {}
    },
    clickTableBtn(row, btn) {
      this.currentRow = cloneDeep(row)

      if (btn.name === 'edit') {
        this.getRoleMenus(row.id)
        this.addForm = {
          name: row.name,
          code: row.code,
          description: row.description
        }
        this.isEdit = true
        this.addDialogVisible = true
        return
      }

      if (btn.name === 'del') {
        this.$confirm(`确认删除角色${row.name}吗？删除后不可恢复`)
          .then((res) => {
            this.tableLoading = true
            api.delRole({ roleId: row.id }).then((res) => {
              hint.success('删除成功')
              this.getList()
            })
          })
          .catch((e) => {
            this.tableLoading = true
          })

        return
      }

      if (btn.name === 'authority') {
        this.authorityDialogVisible = true
        this.getRoleMenus(row.id)
        return
      }

      if (btn.name === 'member') {
        this.memberDialogVisible = true
        this.getUserList()
        return
      }
    },
    search() {},
    getRoleMenus(id) {
      this.authorityDialogLoading = true
      api.getRoleMenus({ roleId: id }).then((res) => {
        this.permissionIds = []
        this.defaultTreeChecked = []
        this.filterIds(res)
        this.authorityDialogLoading = false
      })
    },
    filterIds(arr) {
      arr.forEach((item) => {
        this.permissionIds.push(item.permissionId)
        if (item.child && item.child.length > 0) {
          this.filterIds(item.child)
        } else {
          this.defaultTreeChecked.push(item.permissionId)
        }
      })
    },
    getUserListByRole() {
      this.rightLoading = true
      api
        .getUserListByRole({ roleId: this.currentRow.id })
        .then((res) => {
          this.rightLoading = false
          this.currentUserList = res
          this.totalList = this.userList.concat(this.currentUserList)
        })
    },
    changeTablePage(val) {
      this.params.pageIndex = val
      this.getList()
    }
  }
}
</script>
<style lang="scss" scoped>
.detail-drawer {
  .body {
    padding-bottom: 60px;
  }

  .footer {
    position: absolute;
    z-index: 1001;
    bottom: 0;
    left: 0;
    right: 0;
    padding: 8px;
    background: #fff;
    box-shadow: 0 -1px 6px rgba($color: #333, $alpha: 0.2);
  }
}
</style>
